#include "GInputManager.h"
#include "GInputDevice.h"
#include "GInputModule.h"
#include "GModuleManager.h"
#include "GTimer.h"
#include "GError.h"
#include "GCore.h"


namespace GEngine
{

	GInputManager::GInputManager()
	{
	}
	
	GInputManager::~GInputManager()
	{
	}

	void GInputManager::RegisterDevice(const char* Name, GInputDevice* Device)
	{
		InputDevices.insert(DeviceMap::value_type(Name, Device));
	}

	void GInputManager::UnregisterDevice(const char* Name)
	{
		InputDevices.erase(Name);
	}

	GInputModule* GInputManager::GetModule(const char* ModuleName) const
	{
		ModuleMap::const_iterator Iter = InputModules.find(ModuleName);

		return Iter == InputModules.end() ? NULL : Iter->second;
	}

	GInputDevice* GInputManager::GetDevice(const char* DeviceName) const
	{
		DeviceMap::const_iterator Iter = InputDevices.find(DeviceName);

		return Iter == InputDevices.end() ? NULL : Iter->second;
	}

	// Updates all the child modules
	bool GInputManager::Update(float ElapsedTime)
	{
		ModuleMap::const_iterator End = InputModules.end();
		ModuleMap::const_iterator Iter = InputModules.begin();

		while (Iter != End)
		{
			Iter->second->Update(ElapsedTime);
			Iter++;
		}

		return true;
	}

	bool GInputManager::Initialize() OVERRIDE
	{
		if (!GInitializable::Initialize())
		{
			return false;
		}

		//! Load every module that implements GInputModule
		//! These modules will be included into build by cmake
		GSize ModuleCount = 1;
		for (GSize I = 0; I < ModuleCount; ++I)
		{
			const char* DefaultModule = "GRawInputModule";

			// Can we create the module
			GModule* NewModule = mGModuleManager->CreateModule(DefaultModule);
			if (NewModule == NULL)
			{
				return false;
			}

			// Set new module
			GInputModule* Module = static_cast<GInputModule*>(NewModule);

			// Initialize it
			bool Result = Module->Initialize();
			GUtil::GError::DebugCheck(!Result, "InputModule failed to initialize!");

			InputModules.insert(ModuleMap::value_type(Module->GetDescriptor()->GetName(), Module));
		}
		
		return true;
	}

	bool GInputManager::InitializeLate() OVERRIDE
	{
		if (!GInitializable::InitializeLate())
		{
			return false;
		}

		ModuleMap::const_iterator End = InputModules.end();
		ModuleMap::const_iterator Iter = InputModules.begin();

		while (Iter != End)
		{
			bool Result = Iter->second->InitializeLate();
			GUtil::GError::DebugCheck(!Result, "InputModule failed to initialize late!");

			Iter++;
		}

		return true;
	}
	
	void GInputManager::Uninitialize() OVERRIDE
	{
		ModuleMap::const_iterator End = InputModules.end();
		ModuleMap::const_iterator Iter = InputModules.begin();

		while (Iter != End)
		{
			Iter->second->Uninitialize();
			delete Iter->second;

			Iter++;
		}
		InputModules.clear();
		
		GInitializable::Uninitialize();
	}

	void GInputManager::UninitializeEarly() OVERRIDE
	{
		ModuleMap::const_iterator End = InputModules.end();
		ModuleMap::const_iterator Iter = InputModules.begin();

		while (Iter != End)
		{
			Iter->second->UninitializeEarly();
			Iter++;
		}

		GInitializable::UninitializeEarly();
	}
	
}